package cn.getech.data.development.controller;


import cn.getech.data.development.constant.DataDevelopmentBizExceptionEnum;
import cn.getech.data.development.constant.PermissTypeEnum;
import cn.getech.data.development.constant.TableDataType;
import cn.getech.data.development.entity.*;
import cn.getech.data.development.model.vo.DataSecurityConfigVO;
import cn.getech.data.development.model.vo.FieldsConfigVO;
import cn.getech.data.development.model.vo.RowRulesConfigVO;
import cn.getech.data.development.service.*;
import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.data.intelligence.common.utils.R;
import cn.getech.system.center.annotation.SysLog;
import cn.getech.system.center.constant.OperationModulesEnum;
import cn.getech.system.center.constant.OperationTypeEnum;
import cn.getech.system.center.constant.module.ModuleEnum;
import cn.getech.system.center.service.SysUserRoleService;
import cn.getech.system.center.utils.ShiroUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 表行规则信息 前端控制器
 * </p>
 *
 * @author hujz
 * @since 2019-12-18
 */
@RestController
@RequestMapping("/bdp/tableFieldRules")
@Api("数据安全页面")
public class TableFieldRulesController {

    @Autowired
    private TableFieldInfoService tableFieldInfoService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private TableInfoService tableInfoService;
    @Autowired
    private IDataPermissionParamService dataPermissionParamService;
    @Autowired
    private IAllPermissionConfigService allPermissionConfigService;
    @Autowired
    private ITableFieldRulesService tableFieldRulesService;
    @Autowired
    private RangerDataService rangerDataService;

    @ApiOperation("查询该页面，该表的所有信息")
    //@SysLog(value="查询该页面，该表的所有信息",type= OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.DATA_MAP_MODULE_CODE)
    @GetMapping("/data/{tableId}")
    public R getAllData(@PathVariable("tableId") Integer tableId) {
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid) || tableInfoService.tableOwner(uid, tableId)) {
            TableInfo tableInfo = tableInfoService.getById(tableId);
            List<TableFieldInfo> tableFieldInfos = tableFieldInfoService.list(new QueryWrapper<TableFieldInfo>().eq("table_id", tableId).orderByAsc("field_order", "is_partition"));
            if (tableInfo != null) {
                for (TableFieldInfo tableFieldInfo : tableFieldInfos) {
                    if (tableFieldInfo.getColcumLevelId() == null) {
                        tableFieldInfo.setColcumLevelId(allPermissionConfigService.getOne(new QueryWrapper<AllPermissionConfig>().
                                eq("permiss_type", PermissTypeEnum.FIELD_TYPE.getPermissType())).getDataPermissionId());
                    }
                    if (tableFieldInfo.getEncyStyleId() == null) {
                        tableFieldInfo.setEncyStyleId(allPermissionConfigService.getOne(new QueryWrapper<AllPermissionConfig>().
                                eq("permiss_type", PermissTypeEnum.ENCRYPTION_TYPE.getPermissType())).getDataPermissionId());
                    }
                }
                tableInfo.setTableFieldInfos(tableFieldInfos);
            }

            List<DataPermissionParam> dataPermissionParamsField = dataPermissionParamService.list(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.FIELD_TYPE.getPermissType()));
            List<DataPermissionParam> dataPermissionParamsTable = dataPermissionParamService.list(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.TABLE_TYPE.getPermissType()));
            List<DataPermissionParam> dataPermissionParamsEncryption = dataPermissionParamService.list(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.ENCRYPTION_TYPE.getPermissType()));
            List<DataPermissionParam> dataPermissionParamsRowRule = dataPermissionParamService.list(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.ROW_RULE_TYPE.getPermissType()));

            if (tableInfo != null && tableInfo.getTableLevelId() == null) {
                tableInfo.setTableLevelId(allPermissionConfigService.getOne(new QueryWrapper<AllPermissionConfig>().
                        eq("permiss_type", PermissTypeEnum.TABLE_TYPE.getPermissType())).getDataPermissionId());
            }

            List<TableFieldRules> tableFieldRulesList = tableFieldRulesService.getTableFieldRulesList(tableId);

            String[] defaultTableLevel = new String[]{"A", "B", "C", "D", "E"};
            String[] defaultFieldLevel = new String[]{"A", "B", "C", "D", "E"};
//            String[] defaultFieldLevel = new String[]{"1", "2", "3", "4", "5"};
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("tableAndFields", tableInfo);
            jsonObject.put("rowRules", tableFieldRulesList);
            jsonObject.put("tableLevel", dataPermissionParamsTable);
            jsonObject.put("fieldLeve", dataPermissionParamsField);
            jsonObject.put("RowRuleInfo", dataPermissionParamsRowRule);
            jsonObject.put("EncryptionInfo", dataPermissionParamsEncryption);
            jsonObject.put("defaultTableLevel", defaultTableLevel);
            jsonObject.put("defaultFieldLevel", defaultFieldLevel);
            return R.okWithData(jsonObject);
        }
        return R.ok();
    }

    @ApiOperation("保存或更新数据安全页面配置")
    @SysLog(value="保存或更新数据安全页面配置",type= OperationTypeEnum.UPDATECODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.PROJECT_LIST_MODULE_CODE)
    @PostMapping("/save")
    public R saveData(@RequestBody DataSecurityConfigVO dataSecurityConfigVO) {

        Integer tableId = dataSecurityConfigVO.getId();
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid) || tableInfoService.tableOwner(uid, tableId)) {
            tableFieldRulesService.saveAllConfig(dataSecurityConfigVO);
            //生成对应的策略
            rangerDataService.genteratorRangerPolicy(tableId);
        }

        return R.ok();
    }

    @ApiOperation("保存或更新数据安全页面配置的是否加密")
    @SysLog(value="保存或更新数据安全页面配置的是否加密",type= OperationTypeEnum.UPDATECODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.PROJECT_LIST_MODULE_CODE)
    @PostMapping("/updateEnPasswordType")
    public R updateEnPasswordType(@RequestBody FieldsConfigVO fieldsConfigVO) {

        if(null == fieldsConfigVO || null == fieldsConfigVO.getFieldId() || null == fieldsConfigVO.getEncyStyleId()){
            throw new RRException(DataDevelopmentBizExceptionEnum.PARAM_ERROR.getMessage());
        }
        Integer tableFieldId = fieldsConfigVO.getFieldId();
        //根据tableFieldId查询对应的表信息
        TableFieldInfo tableFieldInfo = tableFieldInfoService.getById(tableFieldId);
        if(null == tableFieldInfo){
            throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_FIELD_NOT_FOUND.getMessage());
        }
        TableInfo tableInfo = tableInfoService.getById(tableFieldInfo.getTableId());
        if(null == tableInfo){
            throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_NOT_FOUND.getMessage());
        }
        //验证这段是否是int、long、float 类型的，如果是这些类型的不能加密
        cheackFieldIsNum(tableFieldInfo.getFieldType(),fieldsConfigVO.getEncyStyleId());
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid) || tableInfoService.tableOwner(uid, tableInfo.getId())) {
            tableFieldRulesService.saveEnPassword(fieldsConfigVO.getEncyStyleId(),tableFieldInfo);
        }
        return R.ok();
    }


    private void cheackFieldIsNum(String fieldType, Integer encyStyleId) {
        if(Objects.equals(fieldType.toUpperCase(), TableDataType.BOOLEAN.getName())
                || Objects.equals(fieldType.toUpperCase(), TableDataType.INT.getName())
                || Objects.equals(fieldType.toUpperCase(), TableDataType.FLOAT.getName())
                || Objects.equals(fieldType.toUpperCase(), TableDataType.BIGINT.getName())){
            String noPasswordName = "不加密";
            DataPermissionParam dataPermissionParamsEncryption = dataPermissionParamService.getOne(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.ENCRYPTION_TYPE.getPermissType())
                    .eq("permiss_name",noPasswordName));
            if(null == dataPermissionParamsEncryption){
                throw new RRException(DataDevelopmentBizExceptionEnum.NO_INIT_EN_TYPE.getMessage());
            }
            if(!Objects.equals(encyStyleId,dataPermissionParamsEncryption.getId())){
                throw new RRException(DataDevelopmentBizExceptionEnum.DATA_TYPE_NOT_EN_TYPE.getMessage());
            }
        }
    }


    @ApiOperation("保存或更新数据安全页面行规则配置")
    @SysLog(value="保存或更新数据安全页面行规则配置",type= OperationTypeEnum.UPDATECODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.PROJECT_LIST_MODULE_CODE)
    @PostMapping("/saveRowRule")
    public R saveRowRule(@RequestBody RowRulesConfigVO rowRulesConfigVO) {
        Integer tableId = rowRulesConfigVO.getTableId();
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid) || tableInfoService.tableOwner(uid, tableId)) {
            TableFieldRules tableFieldRules = new TableFieldRules();
            tableFieldRules.setCalValue(rowRulesConfigVO.getCalValue());
            tableFieldRules.setRowParamId(rowRulesConfigVO.getRowParamId());
            tableFieldRules.setRowRuleId(rowRulesConfigVO.getRowRuleId());
            tableFieldRules.setRuleDesc(rowRulesConfigVO.getRuleDesc());
            tableFieldRules.setTableFieldId(rowRulesConfigVO.getRowRuleFieldId());
            tableFieldRules.setTableId(tableId);
            if (rowRulesConfigVO.getId() != null) {
                tableFieldRules.setId(rowRulesConfigVO.getId());
            }
            tableFieldRulesService.saveOrUpdate(tableFieldRules);
            //更新所有的策略
            rangerDataService.saveOrUpdateRangerPolicy(tableFieldRules);
            return R.okWithData(tableFieldRules);
        }
        throw new RRException("无权限操作行规则");
    }


    @ApiOperation("删除数据安全页面行规则配置")
    @SysLog(value="删除数据安全页面行规则配置",type= OperationTypeEnum.DELETECODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.PROJECT_LIST_MODULE_CODE)
    @PostMapping("/delRowRule")
    public R delRowRule(@RequestBody Map<String, Object> map) {
        if (null == map || null == map.get("tableId")) {
            throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_ID_NOT_FOUND.getMessage());
        }
        if (null == map.get("rowRuleId")) {
            throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_RULES_ID_NOT_FOUND.getMessage());
        }
        tableFieldRulesService.deleteInfo(Integer.parseInt(map.get("tableId").toString()), Integer.parseInt(map.get("rowRuleId").toString()));
        return R.ok();
    }
}

